package org.linlinjava.litemall.admin.service;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.linlinjava.litemall.admin.beans.dto.MerchandiseAllinone;
import org.linlinjava.litemall.admin.beans.enums.PromptEnum;
import org.linlinjava.litemall.admin.beans.vo.MerchandiseVo;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;


/**
 * 管理商品服务
 *
 * @author yliyun
 * @date 2022/09/14
 */
@Service
@RequiredArgsConstructor
public class AdminMerchandiseService {
    /**
     * 商品服务
     */
    private final LitemallMerchandiseService merchandiseService;

    private final LitemallGoodsSpecificationMerchandiseService goodsSpecificationMerchandiseService;

    private final LitemallGoodsAccessoryService litemallGoodsAccessoryService;
    /**
     * 商店商品服务
     */
    private final LitemallShopMerchandiseService shopMerchandiseService;
    /**
     * 商品日志服务
     */
    private final LitemallMerchandiseLogService merchandiseLogService;

    /**
     * litemall店服务
     */
    private final LitemallShopService litemallShopService;

    private final LitemallMerchandiseService litemallMerchandiseService;

    private final LitemallShopMerchandiseService litemallShopMerchandiseService;
    private final LitemallOrderFormulaMaterialService litemallOrderFormulaMaterialService;

    private final LitemallOrderGoodsService litemallOrderGoodsService;

    /**
     * 列表
     * 原料列表
     *
     * @param name          名字
     * @param merchandiseSn 商品sn
     * @param page          页面
     * @param limit         限制
     * @param sort          排序
     * @param order         订单
     * @return {@link Object}
     */
    public Object list(String name, String merchandiseSn, Integer page, Integer limit, String sort, String order) {
        List<LitemallMerchandise> litemallMerchandises = merchandiseService.querySelective(name, merchandiseSn, page, limit, sort, order);
        litemallMerchandises.stream().forEach(merchandise->{

            merchandise.setShopName(ObjectUtil.isNotNull(merchandise.getShopId())?litemallShopService.findById(merchandise.getShopId()).getName():null);
        });
        return ResponseUtil.okList(litemallMerchandises);
    }

    /**
     * 创建
     * 添加货品
     *
     * @param litemallMerchandise litemall商品
     * @return {@link Object}
     */
    public Object create(LitemallMerchandise litemallMerchandise){

        if(StringUtils.isEmpty(litemallMerchandise.getMerchandiseSn()) && StringUtils.isEmpty(litemallMerchandise.getName())){
            return ResponseUtil.fail(PromptEnum.P_101.getCode(), PromptEnum.P_101.getDesc());
        }
        LitemallAdmin admin = getLitemallAdmin();
        litemallMerchandise.setAddUserId(admin.getId());
        litemallMerchandise.setUpdateUserId(admin.getId());
        merchandiseService.create(litemallMerchandise);
        return ResponseUtil.ok();
    }

    /**
     * 更新
     * 修改货品
     *
     * @param merchandiseAllinone 商品allinone
     * @param shopId              商店id
     * @return {@link Object}
     */
    public Object update(MerchandiseAllinone merchandiseAllinone, Integer shopId){

        Integer userId = getLitemallAdmin().getId();
        //修改门店货品
        if(!ObjectUtils.isEmpty(shopId)){
            LitemallShopMerchandise litemallShopMerchandise = merchandiseAllinone.getLitemallShopMerchandise();
            litemallShopMerchandise.setUpdateUserId(userId);
            shopMerchandiseService.updateById(litemallShopMerchandise);
            return ResponseUtil.ok();
        }

        LitemallMerchandise litemallMerchandise = merchandiseAllinone.getLitemallMerchandise();
        if(ObjectUtils.isEmpty(litemallMerchandise.getId())){
            return ResponseUtil.fail(PromptEnum.P_101.getCode(), PromptEnum.P_101.getDesc());
        }
        litemallMerchandise.setUpdateUserId(userId);
        merchandiseService.updateById(litemallMerchandise);
        return ResponseUtil.ok();
    }


    /**
     * 读
     * 获取货品详情
     *
     * @param id     id
     * @param shopId 商店id
     * @return {@link Object}
     */
    public Object read(Integer id, Integer shopId){
        if(null != shopId){
            return ResponseUtil.ok(shopMerchandiseService.queryById(id, shopId));
        }
        return ResponseUtil.ok(merchandiseService.findById(id));
    }

    /**
     * 删除
     * 删除货品
     *
     * @param id     id
     * @param shopId 商店id
     * @return {@link Object}
     */
    public Object delete(Integer id, Integer shopId){

        if(ObjectUtils.isEmpty(id)){
            return ResponseUtil.fail(PromptEnum.P_101.getCode(), PromptEnum.P_101.getDesc());
        }
        //删除门店货品
        if(!ObjectUtils.isEmpty(shopId)){
            shopMerchandiseService.deleteById(id);
            return ResponseUtil.ok();
        }
        LitemallMerchandise litemallMerchandise = new LitemallMerchandise();
        litemallMerchandise.setId(id);
        litemallMerchandise.setUpdateUserId(getLitemallAdmin().getId());
        merchandiseService.deleteById(litemallMerchandise);
        return ResponseUtil.ok();
    }

    /**
     * 货物产品记录列表
     * 出库入库列表
     *
     * @param merchandiseId   商品id
     * @param merchandiseName 商品名称
     * @param orderSn         订单sn
     * @param shopId          商店id
     * @param page            页面
     * @param limit           限制
     * @param sort            排序
     * @param order           订单
     * @return {@link Object}
     */
    public Object goodsProductRecordList(Integer merchandiseId, String merchandiseName, String orderSn, Integer shopId, Integer page,
                                         Integer limit, String sort, String order) {
        return ResponseUtil.okList(merchandiseLogService.querySelective(merchandiseId, merchandiseName, orderSn, shopId, page, limit, sort, order));
    }

    /**
     * 所有
     * 货品列表
     *
     * @return {@link Object}
     */
    public Object all(Integer goodsId) {
        List<LitemallMerchandise> all = merchandiseService.all();
        if(goodsId!=null){
            List<LitemallGoodsSpecificationMerchandise> goodsSpecificationMerchandises = goodsSpecificationMerchandiseService.queryByGid(goodsId);
            List<LitemallGoodsAccessory> goodsAccessoryList = litemallGoodsAccessoryService.queryByGoodsId(goodsId);
            for (LitemallGoodsSpecificationMerchandise goodsSpecificationMerchandise:goodsSpecificationMerchandises){
                for (LitemallGoodsAccessory goodsAccessory:goodsAccessoryList){
                    if (goodsSpecificationMerchandise.getMerchandiseId().equals(goodsAccessory.getMerchandiseId())){
                        for (LitemallMerchandise merchandise : all) {
                            if (merchandise.getId().equals(goodsSpecificationMerchandise.getMerchandiseId())) {
                                merchandise.setIsRrc(true);
                            }
                        }
                    }
                }
            }
        }
        //查询所有货品
        return ResponseUtil.ok(all);
    }


    /**
     * 添加数量
     * TODO 此处没有使用乐观锁判断数据更新，可能存在库存问题
     *
     * @param vo 签证官
     * @return {@link Object}
     */
    @Transactional
    public Object addNumber(MerchandiseVo vo) {
        LitemallMerchandise litemallMerchandise = merchandiseService.findById(vo.getId());

        LitemallMerchandise updateData = new LitemallMerchandise();
        updateData.setId(vo.getId());
        updateData.setNumber(vo.getNumber() + litemallMerchandise.getNumber());
        litemallMerchandise.setUpdateUserId(getLitemallAdmin().getId());
        merchandiseService.updateById(updateData);
        return ResponseUtil.ok();
    }

    /**
     * 数
     * 查询门店库存数量
     *
     * @param shopId        商店id
     * @param merchandiseSn 商品sn
     * @return {@link Object}
     */
    public Object count(Integer shopId, String merchandiseSn) {
        LitemallMerchandise mer = merchandiseService.queryBySn(merchandiseSn);
        if(mer != null){
            LitemallShopMerchandise litemallShopMerchandise = shopMerchandiseService.queryByMerIdAndShopId(mer.getId(), shopId);
            if(null != litemallShopMerchandise && null != litemallShopMerchandise.getNumber()){
                return ResponseUtil.ok(litemallShopMerchandise.getNumber());
            }
        }
        return ResponseUtil.ok(0);
    }

    /**
     * 数
     * 查询门店库存数量
     *
     * @param shopId        商店id
     * @param merchandiseId 商品id
     * @return {@link Object}
     */
    public Object count(Integer shopId, Integer merchandiseId) {
        LitemallShopMerchandise shopMerchandise = shopMerchandiseService.queryByMerIdAndShopId(merchandiseId, shopId);
        if(shopMerchandise != null){
            return ResponseUtil.ok(shopMerchandise.getNumber());
        }else{
            return ResponseUtil.ok(0);
        }
    }

    /**
     * 得到litemall管理
     *
     * @return {@link LitemallAdmin}
     */
    private LitemallAdmin getLitemallAdmin() {
        return (LitemallAdmin) SecurityUtils.getSubject().getPrincipal();
    }


    /**
     * 更新价格
     *
     * @param vo     签证官
     * @param shopId 商店id
     * @return {@link Object}
     */
    public Object updatePrice(MerchandiseVo vo, Integer shopId) {
        LitemallShopMerchandise shopMerchandise = shopMerchandiseService.queryByMerIdAndShopId(vo.getId(), shopId);
        if(shopMerchandise != null){
            LitemallShopMerchandise update = new LitemallShopMerchandise();
            update.setId(shopMerchandise.getId());
            update.setSellPrice(vo.getSellingPrice());
        }
        return null;
    }

    /**
     * 统计数据
     *
     * @param merchandiseName 商品名称
     * @param merchandiseSn   商品sn
     * @param beginTime       开始时间
     * @param endTime         结束时间
     * @param page            页面
     * @param limit           限制
     * @return {@link Object}
     */
    public Object statistics(String merchandiseName,
    		String merchandiseSn, String beginTime, String endTime, int page, int limit) {
        List<LitemallShop> shopList = litemallShopService.getShopAll();
        // 生成基础查询条件
        IPage<LitemallShopMerchandise> shopMerchandiseList = litemallShopMerchandiseService.selectJoinListPage(new Page<>(page, limit),LitemallShopMerchandise.class,new MPJLambdaWrapper<LitemallShopMerchandise>()
                .selectAll(LitemallShopMerchandise.class)
                .like(StrUtil.isNotBlank(merchandiseName),LitemallMerchandise::getName,merchandiseName)
                .leftJoin(LitemallMerchandise.class,LitemallMerchandise::getId,LitemallShopMerchandise::getMerchandiseId));


        List<ShopMerchandiseStatisticsVo> shopMerchandiseStatisticsList = CollStreamUtil.toList(shopMerchandiseList.getRecords(),shopMerchandise -> {
            LitemallMerchandise merchandise = litemallMerchandiseService.findById(shopMerchandise.getMerchandiseId());
            List<LitemallOrderFormulaMaterial> orderFormulaMaterials = litemallOrderFormulaMaterialService.selectByOrderMaterialIdList(merchandise.getId());
            //消耗量(盘点单位)
            BigDecimal consumerNum = BigDecimal.ZERO;
            //损耗量(盘点单位)
            BigDecimal lossNum = BigDecimal.ZERO;
            for (LitemallOrderFormulaMaterial orderFormulaMaterial : orderFormulaMaterials) {
                LitemallOrderGoods orderGoods = litemallOrderGoodsService.findById(orderFormulaMaterial.getOrderGoodsId());
                //单次消耗剂量
                Double onceConsumedDose = orderGoods.getNumber() * orderFormulaMaterial.getSpecificationsDose() * orderFormulaMaterial.getQuantity();
                //单次损耗剂量
                BigDecimal onceLossDose = orderFormulaMaterial.getConsumeSystem().multiply(new BigDecimal(onceConsumedDose));
                //单次使用剂量
                BigDecimal onceUseDose = new BigDecimal(onceConsumedDose).subtract(onceLossDose);
                consumerNum = consumerNum.add(onceUseDose);
                lossNum = lossNum.add(onceLossDose);
            }

            LitemallShop litemallShop = CollUtil.findOne(shopList, shop -> shop.getId() == shopMerchandise.getShopId().intValue());

            ShopMerchandiseStatisticsVo statisticsVo = new ShopMerchandiseStatisticsVo();
            statisticsVo.setStandard(merchandise.getStandard());
            statisticsVo.setMerchandiseId(merchandise.getId());
            statisticsVo.setMerchandiseSn(merchandise.getMerchandiseSn());
            statisticsVo.setMerchandiseName(merchandise.getName());
            statisticsVo.setUnit(merchandise.getUnit());

            statisticsVo.setBasicUnit(merchandise.getBasicUnit());
            statisticsVo.setCheckUnit(merchandise.getCheckUnit());
            statisticsVo.setRatio(merchandise.getRatio());
            statisticsVo.setCheckRatio(merchandise.getCheckRatio());
            statisticsVo.setModel(merchandise.getModel());

            // 设置 inNum 和 avgInNum
            statisticsVo.setInNum(new BigDecimal(shopMerchandise.getBasicNumber()));

            // 设置 consumerNum 和 avgConsumerNum
            statisticsVo.setConsumerNum(consumerNum);

            // 设置 lossNum 和 avgLossNum
            statisticsVo.setLossNum(lossNum);

            statisticsVo.setShopId(litemallShop.getId());
            statisticsVo.setShopName(litemallShop.getName());

            return statisticsVo;
        });
        return ResponseUtil.okPage(shopMerchandiseList,shopMerchandiseStatisticsList);

    	/*IPage<MerchandiseStatisticsVo> result = merchandiseService.statistics(merchandiseName, merchandiseSn, beginTime, endTime, page, limit);
        return ResponseUtil.okPage(result);*/
    }

    public Object revise() {
        // 获取所有商品
        List<LitemallMerchandise> merchandises = merchandiseService.all();

        // 按照name分组，使用toLowerCase()将name转换为小写，实现不区分大小写
        Map<String, List<LitemallMerchandise>> groupedByName = merchandises.stream()
                .collect(Collectors.groupingBy(item -> item.getName().toLowerCase()));

        // 对每个分组中数量大于1的商品，求其number总和
        for (Map.Entry<String, List<LitemallMerchandise>> entry : groupedByName.entrySet()) {
            List<LitemallMerchandise> groupedItems = entry.getValue();

            // 如果该分组的商品数量大于1
            if (groupedItems.size() > 1) {
                // 计算number总和
                Double totalNumber = groupedItems.stream()
                        .mapToDouble(LitemallMerchandise::getNumber)
                        .sum();

                // 找出距离今天最近的商品
                LitemallMerchandise nearestItem = groupedItems.stream()
                        .min(Comparator.comparing(LitemallMerchandise::getUpdateTime)) // 根据addTime比较
                        .orElseThrow(() -> new RuntimeException("No item found"));

                // 将总和设置到距离今天最近的商品
                nearestItem.setNumber(totalNumber);
                merchandiseService.updateById(nearestItem);

                // 删除其他商品
                groupedItems.stream()
                        .filter(item -> item != nearestItem)
                        .forEach(item -> merchandiseService.deleteById(item));  // 删除非最近的商品
            }
        }

        return ResponseUtil.ok();
    }

}
